#import "NativeVideoCachePlugin.h"
#import "NativeVideoCacheApi.h"
#import <KTVHTTPCache/KTVHTTPCache.h>
#import <CommonCrypto/CommonCrypto.h>

@interface NativeVideoCachePlugin () <NVCNativeVideoCacheApi, NVCNativeVideoCacheCacheListener, KTVHCDataLoaderDelegate, FlutterStreamHandler>

@property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *cacheStatus;
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *cacheProgress;
@property (nonatomic, strong) NSMutableDictionary<NSString *, KTVHCDataLoader *> *loaderMap;

// EventChannel for cache events
@property (nonatomic, strong) FlutterEventChannel *eventChannel;
@property (nonatomic, strong) FlutterEventSink eventSink;

@property (nonatomic, strong) id<FlutterBinaryMessenger> messenger;
@property (nonatomic, strong) NSTimer *progressTimer;
@end

@implementation NativeVideoCachePlugin

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    NativeVideoCachePlugin* instance = [[NativeVideoCachePlugin alloc] init];
    instance.messenger = [registrar messenger];
    SetUpNVCNativeVideoCacheApi([registrar messenger], instance);
    
    // 设置EventChannel
    instance.eventChannel = [FlutterEventChannel eventChannelWithName:@"native_video_cache/cache_events" 
                                                       binaryMessenger:[registrar messenger]];
    [instance.eventChannel setStreamHandler:instance];
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _cacheStatus = [[NSMutableDictionary alloc] init];
        _cacheProgress = [[NSMutableDictionary alloc] init];
        _loaderMap = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (void)dealloc {
    [self.progressTimer invalidate];
    self.progressTimer = nil;
    
    // 清理所有loader
    for (KTVHCDataLoader *loader in self.loaderMap.allValues) {
        [loader close];
    }
    [self.loaderMap removeAllObjects];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)logMessage:(NSString *)message {
    NSLog(@"%@", message);
    // 通过Flutter的print输出日志，确保可见
    // FlutterMethodChannel* channel = [FlutterMethodChannel 
    //     methodChannelWithName:@"native_video_cache/debug" 
    //     binaryMessenger:self.messenger];
    // [channel invokeMethod:@"log" arguments:message];
}

#pragma mark - NVCNativeVideoCacheApi Implementation

- (void)initializeConfig:(NVCCacheConfig *)config 
              completion:(void (^)(FlutterError * _Nullable))completion {
    @try {
        [self logMessage:@"iOS缓存系统初始化开始"];
        
        // 停止现有代理服务器
        [KTVHTTPCache proxyStop];
        
        // 设置最大缓存大小
        if (config.maxCacheSize) {
            [KTVHTTPCache cacheSetMaxCacheLength:[config.maxCacheSize longLongValue]];
            [self logMessage:[NSString stringWithFormat:@"设置最大缓存大小: %lld", [config.maxCacheSize longLongValue]]];
        } else {
            [KTVHTTPCache cacheSetMaxCacheLength:1024 * 1024 * 1024]; // 默认1GB
        }
        
        // 设置超时时间
        if (config.connectTimeout) {
            NSTimeInterval timeout = [config.connectTimeout doubleValue] / 1000.0;
            [KTVHTTPCache downloadSetTimeoutInterval:timeout];
            [self logMessage:[NSString stringWithFormat:@"设置超时时间: %.1fs", timeout]];
        }
        
        // 启用日志输出以便调试
        [KTVHTTPCache logSetConsoleLogEnable:YES];
        
        // 启动代理服务器
        NSError *error = nil;
        [KTVHTTPCache proxyStart:&error];
        
        if (error) {
            [self logMessage:[NSString stringWithFormat:@"KTVHTTPCache启动失败: %@", error.localizedDescription]];
            completion([FlutterError errorWithCode:@"INITIALIZATION_ERROR" 
                                           message:error.localizedDescription 
                                           details:nil]);
            return;
        }
        
        // 初始化完成后，输出可能的缓存目录信息以便调试
        [self logCacheDirectoryInfo];
        
        [self logMessage:@"iOS缓存系统初始化成功"];
        completion(nil);
    } @catch (NSException *exception) {
        [self logMessage:[NSString stringWithFormat:@"初始化异常: %@", exception.reason]];
        completion([FlutterError errorWithCode:@"INITIALIZATION_ERROR" 
                                       message:exception.reason 
                                       details:nil]);
    }
}

// 新增方法：输出缓存目录信息
- (void)logCacheDirectoryInfo {
    NSArray *searchPaths = @[
        NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject,
        NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject,
        NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES).firstObject,
        NSTemporaryDirectory()
    ];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    for (NSString *basePath in searchPaths) {
        [self logMessage:[NSString stringWithFormat:@"检查目录: %@", basePath]];
        
        // 检查基础目录下的所有子目录
        NSError *error = nil;
        NSArray *contents = [fileManager contentsOfDirectoryAtPath:basePath error:&error];
        
        if (contents) {
            for (NSString *item in contents) {
                if ([item containsString:@"KTV"] || [item containsString:@"Cache"] || [item containsString:@"HTTP"]) {
                    NSString *fullPath = [basePath stringByAppendingPathComponent:item];
                    BOOL isDirectory;
                    if ([fileManager fileExistsAtPath:fullPath isDirectory:&isDirectory] && isDirectory) {
                        long long size = [self calculateDirectorySize:fullPath];
                        [self logMessage:[NSString stringWithFormat:@"发现可能的缓存目录: %@ (大小: %lld bytes)", fullPath, size]];
                    }
                }
            }
        }
    }
}

- (void)getProxyUrlOriginalUrl:(NSString *)originalUrl 
                    completion:(void (^)(NSString * _Nullable, FlutterError * _Nullable))completion {
    NSURL *url = [NSURL URLWithString:originalUrl];
    if (!url) {
        completion(nil, [FlutterError errorWithCode:@"INVALID_URL" 
                                            message:@"无效的URL" 
                                            details:nil]);
        return;
    }
    
    // 检查是否已完全缓存
    NSURL *cacheCompleteURL = [KTVHTTPCache cacheCompleteFileURLWithURL:url];
    if (cacheCompleteURL) {
        [self logMessage:[NSString stringWithFormat:@"视频已完全缓存，返回本地URL: %@", cacheCompleteURL.absoluteString]];
        completion(cacheCompleteURL.absoluteString, nil);
        return;
    }
    
    // 生成代理URL
    NSURL *proxyURL = [KTVHTTPCache proxyURLWithOriginalURL:url];
    [self logMessage:[NSString stringWithFormat:@"生成代理URL: %@ -> %@", originalUrl, proxyURL.absoluteString]];
    completion(proxyURL.absoluteString, nil);
}

- (void)startCacheUrl:(NSString *)url 
           completion:(void (^)(FlutterError * _Nullable))completion {
    NSURL *originalURL = [NSURL URLWithString:url];
    if (!originalURL) {
        completion([FlutterError errorWithCode:@"INVALID_URL" 
                                       message:@"无效的URL" 
                                       details:nil]);
        return;
    }
    
    [self logMessage:[NSString stringWithFormat:@"开始缓存: %@", url]];
    
    // 检查是否已经在缓存中
    if (self.loaderMap[url]) {
        [self logMessage:[NSString stringWithFormat:@"该URL已经在缓存中: %@", url]];
        completion(nil);
        return;
    }
    
    // 创建DataRequest，使用空的headers
    KTVHCDataRequest *request = [[KTVHCDataRequest alloc] initWithURL:originalURL headers:@{}];
    
    // 创建DataLoader
    KTVHCDataLoader *loader = [KTVHTTPCache cacheLoaderWithRequest:request];
    
    if (loader) {
        // 保存loader引用，防止被释放
        self.loaderMap[url] = loader;
        
        // 设置delegate
        loader.delegate = self;
        
        // 更新状态
        self.cacheStatus[url] = @(NVCCacheStatusCaching);
        self.cacheProgress[url] = @(0.0);
        
        // 触发初始缓存事件
        FlutterError *error = nil;
        [self onCacheStatusChangedUrl:url status:NVCCacheStatusCaching error:&error];
        [self onCacheProgressChangedUrl:url progress:0.0 error:&error];
        
        // 开始预加载
        [loader prepare];
        
        [self logMessage:[NSString stringWithFormat:@"DataLoader创建成功，开始预加载: %@", url]];
        completion(nil);
    } else {
        [self logMessage:[NSString stringWithFormat:@"DataLoader创建失败: %@", url]];
        completion([FlutterError errorWithCode:@"LOADER_CREATE_ERROR" 
                                       message:@"无法创建缓存加载器" 
                                       details:nil]);
    }
}

- (void)stopCacheUrl:(NSString *)url 
          completion:(void (^)(FlutterError * _Nullable))completion {
    [self logMessage:[NSString stringWithFormat:@"停止缓存: %@", url]];
    
    KTVHCDataLoader *loader = self.loaderMap[url];
    if (loader) {
        [loader close];
        [self.loaderMap removeObjectForKey:url];
    }
    
    [self.cacheStatus removeObjectForKey:url];
    [self.cacheProgress removeObjectForKey:url];
    
    completion(nil);
}

- (void)getCacheInfoUrl:(NSString *)url 
             completion:(void (^)(NVCCacheInfo * _Nullable, FlutterError * _Nullable))completion {
    NSURL *originalURL = [NSURL URLWithString:url];
    if (!originalURL) {
        completion(nil, [FlutterError errorWithCode:@"INVALID_URL" 
                                            message:@"无效的URL" 
                                            details:nil]);
        return;
    }
    
    // 获取缓存信息
    KTVHCDataCacheItem *cacheItem = [KTVHTTPCache cacheCacheItemWithURL:originalURL];
    
    NVCCacheStatus status = NVCCacheStatusNone;
    double progress = 0.0;
    long long cachedSize = 0;
    long long totalSize = 0;
    
    if (cacheItem) {
        cachedSize = cacheItem.cacheLength;
        totalSize = cacheItem.totalLength;
        
        if (totalSize > 0) {
            progress = (double)cachedSize / (double)totalSize;
            if (progress >= 1.0) {
                status = NVCCacheStatusCached;
            } else if (cachedSize > 0) {
                status = NVCCacheStatusCaching;
            } else {
                status = NVCCacheStatusNone;
            }
        }
    }
    
    // 检查是否正在下载
    if (self.loaderMap[url]) {
        status = NVCCacheStatusCaching;
    }
    
    NVCCacheInfo *cacheInfo = [NVCCacheInfo makeWithOriginalUrl:url
                                                         status:status
                                                       progress:progress
                                                     cachedSize:cachedSize
                                                      totalSize:totalSize
                                                   errorMessage:nil];
    
    completion(cacheInfo, nil);
}

- (void)clearAllCacheWithCompletion:(void (^)(FlutterError * _Nullable))completion {
    [self logMessage:@"=== 开始清理所有缓存 ==="];
    
    // 停止所有正在进行的下载
    [self logMessage:[NSString stringWithFormat:@"停止 %lu 个正在进行的下载", (unsigned long)self.loaderMap.count]];
    for (KTVHCDataLoader *loader in self.loaderMap.allValues) {
        [loader close];
    }
    [self.loaderMap removeAllObjects];
    [self.cacheStatus removeAllObjects];
    [self.cacheProgress removeAllObjects];
    
    @try {
        // 停止代理服务器
        [KTVHTTPCache proxyStop];
        [self logMessage:@"已停止代理服务器"];
        
        // 清理前先记录当前缓存状态
        [self logMessage:@"清理前的缓存目录状态:"];
        [self logCacheDirectoryInfo];
        
        // 查找KTVHTTPCache可能的缓存目录
        NSArray *possiblePaths = @[
            // Documents目录下
            [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"KTVHTTPCache"],
            // Library/Caches目录下
            [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"KTVHTTPCache"],
            // tmp目录下
            [NSTemporaryDirectory() stringByAppendingPathComponent:@"KTVHTTPCache"],
            // 其他可能的路径
            [[NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"KTVHTTPCache"]
        ];
        
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL foundAndDeleted = NO;
        int deletedCount = 0;
        
        for (NSString *cachePath in possiblePaths) {
            [self logMessage:[NSString stringWithFormat:@"检查缓存路径: %@", cachePath]];
            
            if ([fileManager fileExistsAtPath:cachePath]) {
                [self logMessage:[NSString stringWithFormat:@"✓ 找到缓存目录: %@", cachePath]];
                
                // 先列出目录内容
                NSError *listError = nil;
                NSArray *contents = [fileManager contentsOfDirectoryAtPath:cachePath error:&listError];
                if (contents) {
                    [self logMessage:[NSString stringWithFormat:@"目录包含 %lu 个项目", (unsigned long)contents.count]];
                    for (NSString *item in contents) {
                        [self logMessage:[NSString stringWithFormat:@"  - %@", item]];
                    }
                } else {
                    [self logMessage:[NSString stringWithFormat:@"无法列出目录内容: %@", listError.localizedDescription]];
                }
                
                NSError *error = nil;
                BOOL success = [fileManager removeItemAtPath:cachePath error:&error];
                if (success) {
                    [self logMessage:[NSString stringWithFormat:@"✓ 成功删除缓存目录: %@", cachePath]];
                    foundAndDeleted = YES;
                    deletedCount++;
                } else {
                    [self logMessage:[NSString stringWithFormat:@"✗ 删除缓存目录失败: %@ - %@", cachePath, error.localizedDescription]];
                }
            } else {
                [self logMessage:[NSString stringWithFormat:@"✗ 缓存目录不存在: %@", cachePath]];
            }
        }
        
        if (!foundAndDeleted) {
            [self logMessage:@"⚠️ 未找到任何缓存目录"];
        } else {
            [self logMessage:[NSString stringWithFormat:@"✓ 共删除了 %d 个缓存目录", deletedCount]];
        }
        
        // 清理后再次检查缓存状态
        [self logMessage:@"清理后的缓存目录状态:"];
        [self logCacheDirectoryInfo];
        
        // 重新启动代理服务器
        NSError *proxyError = nil;
        [KTVHTTPCache proxyStart:&proxyError];
        if (proxyError) {
            [self logMessage:[NSString stringWithFormat:@"✗ 重启代理服务器失败: %@", proxyError.localizedDescription]];
        } else {
            [self logMessage:@"✓ 代理服务器已重新启动"];
        }
        
        // 强制刷新内部状态 - 等待一段时间让系统稳定
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self logMessage:@"强制刷新缓存状态"];
            // 清空内部状态记录
            [self.loaderMap removeAllObjects];
            [self.cacheStatus removeAllObjects];
            [self.cacheProgress removeAllObjects];
        });
        
        [self logMessage:@"=== 清理所有缓存完成 ==="];
        completion(nil);
    } @catch (NSException *exception) {
        [self logMessage:[NSString stringWithFormat:@"✗ 清理缓存异常: %@", exception.reason]];
        
        // 确保代理服务器重新启动
        NSError *proxyError = nil;
        [KTVHTTPCache proxyStart:&proxyError];
        
        completion([FlutterError errorWithCode:@"CACHE_DELETE_ERROR" 
                                       message:exception.reason 
                                       details:nil]);
    }
}

- (void)clearCacheUrl:(NSString *)url 
           completion:(void (^)(FlutterError * _Nullable))completion {
    [self logMessage:[NSString stringWithFormat:@"=== 开始清理缓存: %@ ===", url]];
    
    // 停止下载
    KTVHCDataLoader *loader = self.loaderMap[url];
    if (loader) {
        [self logMessage:@"停止正在进行的下载"];
        [loader close];
        [self.loaderMap removeObjectForKey:url];
    } else {
        [self logMessage:@"该URL没有正在进行的下载"];
    }
    
    [self.cacheStatus removeObjectForKey:url];
    [self.cacheProgress removeObjectForKey:url];
    
    @try {
        // 尝试删除对应URL的缓存文件
        NSURL *originalURL = [NSURL URLWithString:url];
        if (originalURL) {
            [self logMessage:[NSString stringWithFormat:@"查找URL缓存文件: %@", url]];
            
            // 查找可能的缓存文件
            NSArray *possibleCachePaths = @[
                [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"KTVHTTPCache"],
                [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"KTVHTTPCache"],
                [NSTemporaryDirectory() stringByAppendingPathComponent:@"KTVHTTPCache"]
            ];
            
            NSFileManager *fileManager = [NSFileManager defaultManager];
            BOOL foundAndDeleted = NO;
            int deletedCount = 0;
            
            // 为URL生成可能的文件名（通常是URL的hash值）
            NSString *urlHash = [self md5HashForString:url];
            [self logMessage:[NSString stringWithFormat:@"URL Hash: %@", urlHash]];
            
            for (NSString *basePath in possibleCachePaths) {
                if ([fileManager fileExistsAtPath:basePath]) {
                    [self logMessage:[NSString stringWithFormat:@"检查缓存目录: %@", basePath]];
                    
                    // 遍历缓存目录查找相关文件
                    NSError *error = nil;
                    NSArray *files = [fileManager contentsOfDirectoryAtPath:basePath error:&error];
                    
                    if (files) {
                        [self logMessage:[NSString stringWithFormat:@"目录包含 %lu 个文件", (unsigned long)files.count]];
                        
                        for (NSString *fileName in files) {
                            BOOL shouldDelete = NO;
                            NSString *reason = @"";
                            
                            if ([fileName containsString:urlHash]) {
                                shouldDelete = YES;
                                reason = @"包含URL hash";
                            } else if ([fileName containsString:[originalURL.host stringByReplacingOccurrencesOfString:@"." withString:@"_"]]) {
                                shouldDelete = YES;
                                reason = @"包含主机名";
                            }
                            
                            if (shouldDelete) {
                                NSString *filePath = [basePath stringByAppendingPathComponent:fileName];
                                [self logMessage:[NSString stringWithFormat:@"找到相关文件: %@ (%@)", fileName, reason]];
                                
                                BOOL isDirectory;
                                if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]) {
                                    NSError *deleteError = nil;
                                    if ([fileManager removeItemAtPath:filePath error:&deleteError]) {
                                        [self logMessage:[NSString stringWithFormat:@"✓ 删除文件: %@", filePath]];
                                        foundAndDeleted = YES;
                                        deletedCount++;
                                    } else {
                                        [self logMessage:[NSString stringWithFormat:@"✗ 删除文件失败: %@ - %@", filePath, deleteError.localizedDescription]];
                                    }
                                }
                            }
                        }
                    } else {
                        [self logMessage:[NSString stringWithFormat:@"无法读取目录: %@", error.localizedDescription]];
                    }
                } else {
                    [self logMessage:[NSString stringWithFormat:@"缓存目录不存在: %@", basePath]];
                }
            }
            
            if (!foundAndDeleted) {
                [self logMessage:[NSString stringWithFormat:@"⚠️ 未找到URL对应的缓存文件: %@", url]];
            } else {
                [self logMessage:[NSString stringWithFormat:@"✓ 共删除了 %d 个相关文件", deletedCount]];
            }
        }
        
        [self logMessage:[NSString stringWithFormat:@"=== 缓存清理完成: %@ ===", url]];
        completion(nil);
    } @catch (NSException *exception) {
        [self logMessage:[NSString stringWithFormat:@"✗ 清理缓存异常: %@ - %@", url, exception.reason]];
        completion([FlutterError errorWithCode:@"CACHE_DELETE_ERROR" 
                                       message:exception.reason 
                                       details:nil]);
    }
}

- (void)getTotalCacheSizeWithCompletion:(void (^)(NSNumber * _Nullable, FlutterError * _Nullable))completion {
    @try {
        // 检查多个可能的缓存目录
        NSArray *possiblePaths = @[
            [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"KTVHTTPCache"],
            [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"KTVHTTPCache"],
            [NSTemporaryDirectory() stringByAppendingPathComponent:@"KTVHTTPCache"]
        ];
        
        long long totalSize = 0;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        for (NSString *cachePath in possiblePaths) {
            if ([fileManager fileExistsAtPath:cachePath]) {
                long long dirSize = [self calculateDirectorySize:cachePath];
                totalSize += dirSize;
                [self logMessage:[NSString stringWithFormat:@"缓存目录 %@ 大小: %lld bytes", cachePath, dirSize]];
            }
        }
        
        [self logMessage:[NSString stringWithFormat:@"总缓存大小: %lld bytes", totalSize]];
        completion(@(totalSize), nil);
    } @catch (NSException *exception) {
        [self logMessage:[NSString stringWithFormat:@"获取总缓存大小异常: %@", exception.reason]];
        completion(@(0), [FlutterError errorWithCode:@"CACHE_SIZE_ERROR" 
                                             message:exception.reason 
                                             details:nil]);
    }
}

// 辅助方法：生成字符串的MD5 hash
- (NSString *)md5HashForString:(NSString *)input {
    const char *str = [input UTF8String];
    unsigned char result[16];
    CC_MD5(str, (CC_LONG)strlen(str), result);
    
    NSMutableString *ret = [NSMutableString stringWithCapacity:32];
    for (int i = 0; i < 16; i++) {
        [ret appendFormat:@"%02x", result[i]];
    }
    return ret;
}

// 辅助方法：递归计算目录大小
- (long long)calculateDirectorySize:(NSString *)directoryPath {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    long long size = 0;
    
    NSError *error = nil;
    NSArray *files = [fileManager contentsOfDirectoryAtPath:directoryPath error:&error];
    
    if (files) {
        for (NSString *file in files) {
            NSString *filePath = [directoryPath stringByAppendingPathComponent:file];
            NSDictionary *attributes = [fileManager attributesOfItemAtPath:filePath error:nil];
            if (attributes) {
                BOOL isDirectory;
                if ([fileManager fileExistsAtPath:filePath isDirectory:&isDirectory]) {
                    if (isDirectory) {
                        size += [self calculateDirectorySize:filePath];
                    } else {
                        size += [attributes fileSize];
                    }
                }
            }
        }
    }
    
    return size;
}

- (void)isCachedUrl:(NSString *)url 
         completion:(void (^)(NSNumber * _Nullable, FlutterError * _Nullable))completion {
    NSURL *originalURL = [NSURL URLWithString:url];
    if (!originalURL) {
        completion(nil, [FlutterError errorWithCode:@"INVALID_URL" 
                                            message:@"无效的URL" 
                                            details:nil]);
        return;
    }
    
    NSURL *cacheCompleteURL = [KTVHTTPCache cacheCompleteFileURLWithURL:originalURL];
    BOOL isCached = (cacheCompleteURL != nil);
    completion(@(isCached), nil);
}

- (void)setCacheListenerWithError:(FlutterError * _Nullable __autoreleasing *)error {
    // delegate方法已在startCache中设置
}

- (void)removeCacheListenerWithError:(FlutterError * _Nullable __autoreleasing *)error {
    // 清理所有delegate
    for (KTVHCDataLoader *loader in self.loaderMap.allValues) {
        loader.delegate = nil;
    }
}

#pragma mark - KTVHCDataLoaderDelegate Implementation

- (void)ktv_loaderDidFinish:(KTVHCDataLoader *)loader {
    NSString *url = [self findURLForLoader:loader];
    if (url) {
        [self logMessage:[NSString stringWithFormat:@"缓存完成: %@", url]];
        self.cacheStatus[url] = @(NVCCacheStatusCached);
        self.cacheProgress[url] = @(1.0);
        
        // 清理loader
        [self.loaderMap removeObjectForKey:url];
        
        // 通知Flutter层
        FlutterError *error = nil;
        [self onCacheStatusChangedUrl:url status:NVCCacheStatusCached error:&error];
        [self onCacheProgressChangedUrl:url progress:1.0 error:&error];
    }
}

- (void)ktv_loader:(KTVHCDataLoader *)loader didFailWithError:(NSError *)error {
    NSString *url = [self findURLForLoader:loader];
    if (url) {
        [self logMessage:[NSString stringWithFormat:@"缓存失败: %@ - %@", url, error.localizedDescription]];
        self.cacheStatus[url] = @(NVCCacheStatusError);
        
        // 清理loader
        [self.loaderMap removeObjectForKey:url];
        
        // 通知Flutter层
        FlutterError *flutterError = nil;
        [self onCacheErrorUrl:url error:error.localizedDescription error:&flutterError];
    }
}

- (void)ktv_loader:(KTVHCDataLoader *)loader didChangeProgress:(double)progress {
    NSString *url = [self findURLForLoader:loader];
    if (url) {
        [self logMessage:[NSString stringWithFormat:@"缓存进度: %@ -> %.1f%%", url, progress * 100]];
        self.cacheProgress[url] = @(progress);
        
        // 通知Flutter层
        FlutterError *error = nil;
        [self onCacheProgressChangedUrl:url progress:progress error:&error];
    }
}

#pragma mark - Private Methods

- (NSString *)findURLForLoader:(KTVHCDataLoader *)loader {
    for (NSString *url in self.loaderMap.allKeys) {
        if (self.loaderMap[url] == loader) {
            return url;
        }
    }
    return nil;
}

#pragma mark - NVCNativeVideoCacheCacheListener Implementation

- (void)onCacheProgressChangedUrl:(NSString *)url 
                         progress:(double)progress 
                            error:(FlutterError * _Nullable __autoreleasing *)error {
    [self logMessage:[NSString stringWithFormat:@"通知Flutter进度变化: %@ -> %.1f%%", url, progress * 100]];
    // 发送缓存进度事件
    [self sendCacheEvent:@"progress" url:url data:@{@"progress": @(progress)}];
}

- (void)onCacheStatusChangedUrl:(NSString *)url 
                         status:(NVCCacheStatus)status 
                          error:(FlutterError * _Nullable __autoreleasing *)error {
    [self logMessage:[NSString stringWithFormat:@"通知Flutter状态变化: %@ -> %d", url, (int)status]];
    // 发送缓存状态事件
    [self sendCacheEvent:@"status" url:url data:@{@"status": @((int)status)}];
}

- (void)onCacheErrorUrl:(NSString *)url 
                  error:(NSString *)errorMessage 
                  error:(FlutterError * _Nullable __autoreleasing *)error {
    [self logMessage:[NSString stringWithFormat:@"通知Flutter缓存错误: %@ -> %@", url, errorMessage]];
    // 发送缓存错误事件
    [self sendCacheEvent:@"error" url:url data:@{@"error": errorMessage}];
}

#pragma mark - EventChannel StreamHandler Methods

- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
    self.eventSink = events;
    return nil;
}

- (FlutterError *)onCancelWithArguments:(id)arguments {
    self.eventSink = nil;
    return nil;
}

#pragma mark - Helper Methods

- (void)sendCacheEvent:(NSString *)type url:(NSString *)url data:(NSDictionary *)data {
    if (self.eventSink) {
        NSMutableDictionary *event = [@{
            @"type": type,
            @"url": url
        } mutableCopy];
        [event addEntriesFromDictionary:data];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            self.eventSink(event);
        });
    }
}

@end 